Skip to content

Challenge 23: verify Vec mod.rs function safety with Kani - #692

Open
kasimte wants to merge 3 commits into
model-checking:mainfrom
kasimte:challenge-23-vec-part1
Open

kasimte wants to merge 3 commits into
model-checking:mainfrom
kasimte:challenge-23-vec-part1

Conversation

@kasimte

@kasimte kasimte commented Sep 22, 2026 •

Copy link
Copy Markdown

Towards Challenge 23: Verify the safety of Vec functions part 1 (issue #284).

Kani harnesses for all 36 listed public Vec functions in alloc::vec::mod.rs. Each runs the function's real body, with no cfg(kani) substitution and no assume(false). All 53 harnesses in vec::verify pass via scripts/run-kani.sh (52 new, plus the pre-existing verify_swap_remove).

Verification

Functions Approach
push, push_within_capacity, spare_capacity_mut, split_at_spare_mut, into_boxed_slice, into_raw_parts_with_alloc, append_elements, extend_trusted, extend_desugared Symbolic unbounded capacity (with_capacity(cap), cap free in 1..=isize::MAX/4). Reallocation runs at symbolic capacity, not a fixed buffer.
from_raw_parts, from_parts, from_parts_in, set_len safety::{requires,ensures} via proof_for_contract. The proofs build valid parts, and pre-initialize set_len's spare region, rather than assuming them. Obligations not expressible as predicates are documented at each contract.
insert, remove, truncate, retain, drain, extract_if, and the rest Symbolic length, bounded per function (see Scope), built with the loop-contract-free kani::vec::any_vec idiom. insert and remove assert the moved element's post-shift position.
retain_mut Real-body loop_invariant + loop_modifies on its in-place loop.
failure and edge arms Both push_within_capacity results, set_len growth, and swap_remove's out-of-bounds panic (#[kani::should_panic]).
drop + alignment insert, remove, truncate, swap_remove, retain, drain also run over a Drop type and #[repr(align(16))].

Every kani::assume is paired with a kani::cover confirming it is satisfiable: 55 covers, 29 assumes.

Scope

Two mandatory criteria are met only in part, both blocked by tool limits at this pin:

  • Unbounded length. A symbolic-unbounded loop_modifies region overflows CBMC's write-set machinery, so loop- and shift-bearing harnesses run at the largest length CBMC completes: 0..=64 for most, 0..=4 or 0..=2 where a shift or in-place loop dominates. A few fix the insert/copy offset, with values still symbolic. Allocation capacity itself is unbounded. Loop contracts on extend_with and dedup_by were non-convergent in CI, so those stay bounded.
  • Generic T (no monomorphization). A Kani harness is monomorphic, so this clause cannot be expressed in Kani, and is deferred to the committee. The harnesses span the element-type axes instead: size, zero-size (Vec<()>), over-alignment (#[repr(align(16))]), and drop glue. On the size axis, RawVec::min_non_zero_cap chooses the initial capacity from size_of::<T>() (one of three arms: == 1, <= 1024, > 1024); new 64- and 1025-byte grow-from-empty harnesses reach the <= 1024 and > 1024 arms (each with a capacity kani::cover), which the u8 harnesses (the == 1 arm) did not.

Changes

Additive (+938/−0). The only shipped-code change beyond Kani-inert attributes is in lib.rs: proc_macro_hygiene becomes unconditional (mirroring core), so retain_mut's #[safety::…] loop attribute is present in every build rather than cfg(kani)-only.

The spec's from_nonnull and from_nonnull_in are from_parts and from_parts_in in the current source.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@kasimte
kasimte requested a review from a team as a code owner September 22, 2026 03:33
@feliperodri feliperodri added the Challenge Used to tag a challenge label Sep 22, 2026
@kasimte
kasimte force-pushed the challenge-23-vec-part1 branch from 39371b5 to 3fb3dc0 Compare October 7, 2026 04:42

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Challenge Used to tag a challenge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants